﻿using Ldt.DataEngine.DataFlowParse.Model;
using LdtDataEngin.ModuleDetail.AnalysisModule.CaseExtract;
using LdtDataEngin.ModuleDetail.BaseModule;
using LdtDataEngin.ModuleDetail.PersonnelAnalysis;
using LdtDataEngin.ModuleDetail.RegCommon;
using LdtJudge.DataEngine.Common;
using LdtJudge.DataEngine.Common.XmlUtility;
using LdtJudge.DataEngine.DataBaseStores;
using LdtJudge.DataEngine.Model;
using LdtJudge.DataEngine.Model.DataModel.DynamicData;
using LdtJudge.DataEngine.Model.DataModel.ElementNode;
using LdtJudge.DataEngine.Model.XMLConfigModel.ConfigModel;
using LdtJudge.DataEngine.Model.XMLConfigModel.DataStores;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text.RegularExpressions;
using System.Xml;

namespace LdtDataEngin.ModuleDetail.CaseExtract
{
    public class ElementExtractionTexTXml : AssermBase
    {
        public ElementExtractionTexTXml(DataContext context)
        {
            dataContext = context;
        }

        public List<ElementNodeModel> elementNodesList = new List<ElementNodeModel>();

        /// <summary>
        /// 案件要素提取
        /// </summary>
        /// <param name="configModel">步骤信息</param>
        /// <param name="ModelName">模块名称</param>
        /// <param name="amountConfig">配置模块</param>
        /// <returns></returns>
        public void Extract(ConfigModel configModel, string ModelName, ConfigModel amountConfig)
        {
            
            XmlUtilCommon xmlUtil = new XmlUtilCommon();
            //解析配置信息
            XmlDocument document=new XmlDocument();
            document.LoadXml(configModel.ConfigContent);
            List<ConfigNodeModel> configList = xmlUtil.ReadConfigNode(document);
            Stopwatch swtext = new Stopwatch();
            swtext.Start(); 
            ReadXmlNode(configList, "0", null, ModelName);
            swtext.Stop();
            dataContext.DataLayerAns.AnalysisResultsXml= AnalyticalXmlDocument();
            XmlUtilCommon xmlUtilCommon = new XmlUtilCommon() { dataContext=dataContext };
            DataSoursModel dataSoursModelResults = new DataSoursModel();
            dataSoursModelResults.dataModelList = xmlUtilCommon.GenerateDataSources();
            List<DataModel> datasList = xmlUtilCommon.AnalysisConvertDataModel();
            dataSoursModelResults.dataModelList = datasList;
            if (dataContext.DataLayerAns.AnalysisResultsDataModel==null)
                dataContext.DataLayerAns.AnalysisResultsDataModel = new DataSoursModel();
            if (dataContext.DataLayerAns.AnalysisResultsDataModel.dataModelList == null)
                dataContext.DataLayerAns.AnalysisResultsDataModel.dataModelList = new List<DataModel>();
            dataContext.DataLayerAns.AnalysisResultsDataModel.dataModelList.AddRange(datasList);
            dataContext.InteractiveShow.LogShow("案件要素中心分析时长" + swtext.Elapsed.TotalMilliseconds.ToString("0"));
            dataContext.InteractiveShow.LogShow("----------------进行案件要素金额内容转换---------------");

            if (amountConfig!=null &&!string.IsNullOrWhiteSpace(amountConfig.ConfigContent))
            {
                string amountmessage = amountConfig.ConfigContent;
                AmountModel elementcofig = XmlUtility.DeserializeToObject<AmountModel>(amountmessage);
                if (elementcofig.bookTypeModelList.FirstOrDefault(a => a.value.ToLower() == dataContext.DataLayerAns.SourceCode.ToLower()) != null)
                {
                    foreach (var item in elementcofig.bookTypeModelList.FirstOrDefault(a => a.value.ToLower() == dataContext.DataLayerAns.SourceCode.ToLower()).xmlLableModelList)
                    {
                        List<DataModel> dataModelConvertList = dataContext.DataLayerAns.AnalysisResultsDataModel.dataModelList.Where(a => a.XmlPath == item.value)?.ToList();
                        foreach (DataModel dataModelConvert in dataModelConvertList)
                        {
                            if (dataModelConvert.AttributesList.FirstOrDefault(a => a.Name == item.attribute) != null)
                            {
                                Source source = dataModelConvert.AttributesList.FirstOrDefault(a => a.Name == item.attribute).sourceList.FirstOrDefault(a => a.IsCheck == "1");
                                source = JsonConvert.DeserializeObject<Source>(JsonConvert.SerializeObject(source));
                                source.SaveValue = source.ExtValue;
                                AttributeInfo attribute = new AttributeInfo();
                                if (dataModelConvert.AttributesList.FirstOrDefault(a => a.Name == item.addattrbuten) != null)
                                {
                                    attribute = dataModelConvert.AttributesList.FirstOrDefault(a => a.Name == item.addattrbuten);
                                    attribute.sourceList = new List<Source>();
                                    attribute.sourceList.Add(source);
                                }
                                else
                                {
                                    attribute.Name = item.addattrbuten;
                                    attribute.sourceList = new List<Source>();
                                    attribute.sourceList.Add(source);
                                    dataModelConvert.AttributesList.Add(attribute);
                                }
                            }
                        }
                    }
                }
            }

            dataContext.InteractiveShow.LogShow("----------------进行案件要素金额内容完毕---------------");
            if (dataContext.DataLayerAns.AnalysisResultsDataModel.dataModelList!=null)
                dataContext.DataLayerAns.AnalysisResultsXml = XmlUtility.DataModelByXml(dataContext.DataLayerAns.AnalysisResultsDataModel.dataModelList);
            dataContext.InteractiveShow.LogShow("案件要素提取时间" + swtext.Elapsed.TotalMilliseconds.ToString());
           dataContext.InteractiveShow.LogShow("@分析结果数据" + dataContext.DataLayerAns.AnalysisResultsXml.OuterXml);

        }

        /// <summary>
        /// 节点信息加载
        /// </summary>
        /// <param name="configList">节点信息</param>
        /// <param name="index">开始序号</param>
        public void ReadXmlNode(List<ConfigNodeModel> configNodeList, string id, ElementNodeModel elementNode, string modelName)
        {
            List<ConfigNodeModel> configList = configNodeList.Where(a => a.ParentID == id).ToList();
            foreach (ConfigNodeModel nodemodel in configList)
            {
                List<string> originalTextList = new List<string>();
                if (elementNode == null)
                {
                    originalTextList.Add(dataContext.DataLayerAns.FengXiCanShu.Juanzongneirong);
                }
                else
                {
                    originalTextList.AddRange(elementNode.OriginalTextList);
                }
                ProcessAnalysis processAnalysis = new ProcessAnalysis(dataContext,modelName);
                InteractiveModel interactiveModel = processAnalysis.AnalysisProcessData(nodemodel.XmlPath, modelName, 2, originalTextList);
                if (interactiveModel != null)
                {
                    if (interactiveModel.IsML)
                    {
                        dataContext.InteractiveShow.LogShow("使用uie机器学习模型进行节点分析：" + nodemodel.XmlPath);
                        try
                        {
                            //通过机器学习-UIE模型提取节点
                            CaseElementMachLearnAssemble UieModelExtract = new CaseElementMachLearnAssemble() { _dataContext = dataContext };
                            var originContent = string.Join("", interactiveModel.NodeTextList);
                            string parentId = elementNode == null ? "0" : elementNode.Id;
                            var uieNodes = UieModelExtract.MachLearnExtract(originContent, parentId, nodemodel.XmlPath, modelName);
                            if (uieNodes != null && uieNodes.Any())
                                dataContext.DataLayerAns.ElementNodeModelsList.AddRange(uieNodes);
                        }
                        catch (System.Exception ex)
                        {

                            dataContext.InteractiveShow.LogShow("节点："+nodemodel.xmlNode+"uie机器模型调用失败.错误原因："+ex.ToString());
                        }
                       
                    }
                    else
                    {
                        //通过正则提取节点数据
                        if (interactiveModel.ModelList.Count > 0)
                        {
                            foreach (string itemoreg in interactiveModel.ModelList)
                            {
                                ElementNodeModel elementNodeModel = new ElementNodeModel();
                                elementNodeModel.Id = Snowflake.Instance().GetId().ToString();
                                elementNodeModel.ParentId = elementNode == null ? "0" : elementNode.Id;
                                elementNodeModel.Path = nodemodel.XmlPath;
                                elementNodeModel.Name = nodemodel.Name;
                                elementNodeModel.IsNode = "1";
                                elementNodeModel.OrigianlTextStr = originalTextList[0];
                                elementNodeModel.OriginalTextList = new List<string>();
                                elementNodeModel.ParagraphName = interactiveModel.ParagraphName;
                                elementNodeModel.DictionariesCode = interactiveModel.DictionariesCode;
                                elementNodeModel.OriginalTextList.Add(itemoreg);
                                if (interactiveModel.ModelDic.ContainsKey("originaltext"))
                                {
                                    elementNodeModel.ExtOriginalText = string.Join("", interactiveModel.ModelDic["originaltext"]);
                                }
                                if (interactiveModel.ModelDic.ContainsKey("rerule"))
                                {
                                    if (interactiveModel.ModelDic["rerule"][0] != null)
                                    {
                                        string jsonString = interactiveModel.ModelDic["rerule"][0].ToString();
                                        if (!string.IsNullOrWhiteSpace(jsonString) && JsonHelper.IsRightJson(jsonString))
                                        {
                                            JArray ja = (JArray)JsonConvert.DeserializeObject(jsonString);
                                            foreach (var jToken in ja)
                                            {
                                                JObject jo = (JObject)jToken;
                                                if (jo["Vlaue"].ToString()== itemoreg)
                                                {
                                                    string index = jo["Index"].ToString();
                                                    string length = jo["Length"].ToString();
                                                    if (!string.IsNullOrEmpty(index))
                                                        elementNodeModel.OriginalLocation = index;
                                                    if (!string.IsNullOrEmpty(length))
                                                        elementNodeModel.OriginalLen = length;
                                                }
                                                
                                            }
                                        }
                                    }
                                }
                                elementNodeModel.interactiveModel = interactiveModel;
                                elementNodesList.Add(elementNodeModel);
                                // 向动态数据层里面的案件要素信息列表添加要素节点
                                if (dataContext.DataLayerAns.ElementNodeModelsList == null)
                                {
                                    dataContext.DataLayerAns.ElementNodeModelsList = new List<ElementNodeModel>();
                                }
                                dataContext.DataLayerAns.ElementNodeModelsList.Add(elementNodeModel);
                                if (nodemodel.DicAttribute.Count > 0)
                                {
                                    foreach (var itemValue in nodemodel.DicAttribute)
                                    {
                                        string Xpath = nodemodel.XmlPath + @"\" + itemValue.Key;

                                        InteractiveModel interactiveModelAttice = processAnalysis.AnalysisProcessData(Xpath, modelName, 2, elementNodeModel.OriginalTextList);

                                        if (interactiveModelAttice != null && interactiveModelAttice.ModelList.Count > 0 && !string.IsNullOrEmpty(interactiveModelAttice.ModelList[0]))
                                        {
                                            ElementNodeModel elementNodeAttice = new ElementNodeModel();
                                            elementNodeAttice.Id = Snowflake.Instance().GetId().ToString();
                                            elementNodeAttice.ParentId = elementNodeModel.Id;
                                            elementNodeAttice.Path = Xpath;
                                            elementNodeAttice.IsNode = "0";
                                            elementNodeAttice.Name = itemValue.Key;
                                            elementNodeAttice.OriginalTextList = interactiveModelAttice.ModelList;
                                            elementNodeAttice.interactiveModel = interactiveModelAttice;
                                            elementNodeAttice.Value = interactiveModelAttice.ModelList[0];
                                            PersonnelConversion personnelConversion = new PersonnelConversion() { spokenamelist = dataContext.DataLayerAns.ElementSpokeList };
                                            elementNodeAttice.Value = interactiveModelAttice.ModelList[0];

                                            elementNodeModel.ParagraphName = interactiveModelAttice.ParagraphName;
                                            elementNodeModel.DictionariesCode = interactiveModelAttice.DictionariesCode;
                                            string joinStr = string.Join("", elementNodeModel.OriginalTextList);
                                            elementNodeAttice.OrigianlTextStr = joinStr;
                                            if (interactiveModelAttice.ModelDic.ContainsKey("originaltext"))
                                            {
                                                elementNodeAttice.ExtOriginalText = interactiveModelAttice.ModelDic["originaltext"][0];
                                            }
                                            if (interactiveModelAttice.ModelDic.ContainsKey("paragraphorg"))
                                            {
                                                elementNodeAttice.OrigianlTextStr = interactiveModelAttice.ModelDic["paragraphorg"][0];
                                            }
                                            if (interactiveModelAttice.ModelDic.ContainsKey("rerule"))
                                            {
                                                if (interactiveModelAttice.ModelDic["rerule"][0] != null)
                                                {
                                                    string jsonString = interactiveModelAttice.ModelDic["rerule"][0].ToString();
                                                    if (!string.IsNullOrWhiteSpace(jsonString)&&JsonHelper.IsRightJson(jsonString))
                                                    {
                                                        JArray ja = (JArray)JsonConvert.DeserializeObject(jsonString);
                                                        foreach (var jToken in ja)
                                                        {
                                                            JObject jo = (JObject)jToken;
                                                            string index = jo["Index"].ToString();
                                                            string length = jo["Length"].ToString();
                                                            if (!string.IsNullOrEmpty(index))
                                                                elementNodeAttice.OriginalLocation = index;
                                                            if (!string.IsNullOrEmpty(length))
                                                                elementNodeAttice.OriginalLen = length;
                                                        }
                                                    }
                                                }
                                            }
                                            elementNodesList.Add(elementNodeAttice);
                                            // 向动态数据层里面的案件要素信息列表添加要素节点
                                            dataContext.DataLayerAns.ElementNodeModelsList.Add(elementNodeAttice);
                                        }
                                    }
                                }
                                ReadXmlNode(configNodeList, nodemodel.Uid, elementNodeModel, modelName);
                            }
                        }
                    }
                }
            }
        }


        /// <summary>
        /// 解析完成XML格式并输出
        /// </summary>
        /// <returns></returns>
        public XmlDocument AnalyticalXmlDocument()
        {
            XmlDocument xmlDocument = new XmlDocument();
            XmlElement rootElement = xmlDocument.CreateElement("temap");
            AnlyticalXmlNodel(rootElement, "0", xmlDocument);
            xmlDocument.AppendChild(rootElement);
            XmlDocument xmlDocumentreust = new XmlDocument();
            foreach (XmlNode node in xmlDocument.SelectNodes("temap/*"))
            {
                xmlDocumentreust.LoadXml(node.OuterXml);
            };
            //dataContext.InteractiveShow.LogShow("解析完成，解析后的XML如下:");
            //dataContext.InteractiveShow.LogShow(xmlDocumentreust.OuterXml);
            return xmlDocumentreust;
        }

        /// <summary>
        /// 创建节点
        /// </summary>
        /// <param name="xmlElementPranet">上级节点</param>
        /// <param name="pid">上级ID</param>
        /// <param name="xmlDocument">结果数据源</param>
        public void AnlyticalXmlNodel(XmlElement xmlElementPranet, string pid, XmlDocument xmlDocument)
        {
            List<ElementNodeModel> elementNodeList = elementNodesList.Where(a => a.ParentId == pid).ToList();
            List<ElementNodeModel> elementNode = elementNodeList.Where(a => a.IsNode == "1").ToList();
            //节点解析
            foreach (ElementNodeModel nodemodel in elementNode)
            {
                ///创建节点
                XmlElement xmlElementNodel = xmlDocument.CreateElement(nodemodel.Name);
                List<ElementNodeModel> elementAttice = elementNodesList.Where(a => a.IsNode == "0" && a.ParentId == nodemodel.Id).ToList();
                foreach (ElementNodeModel nodemodelat in elementAttice)
                {
                    ///创建节点
                    //xmlElementNodel.SetAttribute(nodemodelat.Name, nodemodelat.OriginalTextList[0]);
                    xmlElementNodel.SetAttribute(nodemodelat.Name, nodemodelat.Value);
                }
                xmlElementNodel.SetAttribute("id", nodemodel.Id);
                AnlyticalXmlNodel(xmlElementNodel, nodemodel.Id, xmlDocument);
                xmlElementPranet.AppendChild(xmlElementNodel);
            }
        }
    }
}
